package com.xl.qa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.xl.basic.entity.Properties;
import com.xl.basic.entity.Result;
import com.xl.basic.entity.ResultEnums;
import com.xl.basic.utils.ServletUtils;
import com.xl.dao.domain.XlQuestionOrder;
import com.xl.dao.mapper.XlQuestionOrderMapper;
import com.xl.qa.enmus.QuestionOrderStateEnums;
import com.xl.qa.entity.param.AddQuesWxUnifiedOrderParam;
import com.xl.qa.entity.result.QuesWxUnifiedOrderResult;
import com.xl.qa.service.QuestionWxPayService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * @author 钟勇
 * Create in 2024/1/24 10:43
 */
@Service
@RequiredArgsConstructor
public class QuestionWxPayServiceImpl implements QuestionWxPayService {

    private final WxPayService wxPayService;
    private final XlQuestionOrderMapper orderMapper;
    private final Properties properties;

    @Override
    public Result<QuesWxUnifiedOrderResult> addQuesWxUnifiedOrder(@NonNull AddQuesWxUnifiedOrderParam param) {
        XlQuestionOrder orderInfo = orderMapper.selectById(param.getOrderId());
        if (orderInfo == null || orderInfo.getState() != 1) {
            return ResultEnums.BusinessError.getResult("未找到对应订单");
        }

        if (QuestionOrderStateEnums.getByState(orderInfo.getOrderState()) != QuestionOrderStateEnums.add) {
            return ResultEnums.BusinessError.getResult("订单状态无法支付");
        }

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime payExpireTime = now.plusHours(2);
        String timeFormat = "yyyyMMddHHmmss";

        Properties.Basic basic = properties.getBasic();

        WxPayUnifiedOrderRequest orderParam = new WxPayUnifiedOrderRequest();
        orderParam.setBody(orderInfo.getQuestionTitle());
        orderParam.setOutTradeNo(orderInfo.getOrderId());
        orderParam.setTotalFee(orderInfo.getPrice());
        orderParam.setOpenid(param.getOpenId());
        orderParam.setSpbillCreateIp(ServletUtils.getClientIP());
        orderParam.setTimeStart(LocalDateTimeUtil.format(now, timeFormat));
        orderParam.setTimeExpire(LocalDateTimeUtil.format(payExpireTime, timeFormat));
        orderParam.setTradeType("JSAPI");
        orderParam.setNotifyUrl(basic.getDomain() + "/api/QuestionWxPay/wxQuesOrderPayNotify");

        WxPayMpOrderResult payInfo;
        try {
            payInfo = wxPayService.createOrder(orderParam);
            if (payInfo == null || StrUtil.isBlank(payInfo.getPackageValue())) {
                return ResultEnums.BusinessError.getResult("微信统一下单失败");
            }
        } catch (WxPayException e) {
            return ResultEnums.BusinessError.getResult(e.toString());
        }

        //写入新的订单失效时间
        orderMapper.updateById(new XlQuestionOrder()
                .setOrderId(param.getOrderId())
                .setPayValidTime(payExpireTime)
        );

        QuesWxUnifiedOrderResult data = BeanUtil.copyProperties(payInfo, QuesWxUnifiedOrderResult.class);

        return ResultEnums.Success.getDataResult(data);
    }

    @Override
    public Result<Object> wxQuesOrderPayNotify(String xmlData) {

        WxPayOrderNotifyResult notifyRes;
        try {
            notifyRes = wxPayService.parseOrderNotifyResult(xmlData);
            if (notifyRes == null) {
                return ResultEnums.Exception.getResult("参数解析失败");
            }
        } catch (WxPayException e) {
            return ResultEnums.Exception.getResult(e.toString());
        }

        if (!"SUCCESS".equals(notifyRes.getResultCode())) {
            return ResultEnums.Exception.getResult(notifyRes.getReturnMsg());
        }


        String orderId = notifyRes.getOutTradeNo();
        XlQuestionOrder orderInfo = orderMapper.selectById(orderId);
        if (orderInfo == null || orderInfo.getState() != 1) {
            return ResultEnums.BusinessError.getResult("未找到对应订单");
        }

        if (QuestionOrderStateEnums.getByState(orderInfo.getOrderState()) != QuestionOrderStateEnums.add) {
            return ResultEnums.Success.getResult();
        }

        if (orderMapper.updateById(new XlQuestionOrder()
                .setOrderId(orderId)
                .setPayTime(LocalDateTime.now())
                .setOrderState(QuestionOrderStateEnums.paid.getState())
        ) == 0) {
            return ResultEnums.Exception.getResult("支付状态写入失败");
        }

        return ResultEnums.Success.getResult();
    }
}
